package com.unbook.service.impl;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.unbook.entity.Book;
import com.unbook.entity.BookOnType;
import com.unbook.entity.ResponseVo;
import com.unbook.entity.params.BookInsBody;
import com.unbook.entity.params.BookListByUIdParam;
import com.unbook.entity.params.BookUpdateBody;
import com.unbook.mapper.IBookMapper;
import com.unbook.mapper.IBookOnBookTypeMapper;
import com.unbook.mapper.IBookTypeMapper;
import com.unbook.service.IBookService;
import com.unbook.utils.JwtUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class BookServiceImpl extends ServiceImpl<IBookMapper, Book> implements IBookService {
    @Autowired
    IBookMapper bookMapper;
    @Autowired
    IBookTypeMapper bookTypeMapper;
    @Autowired
    IBookOnBookTypeMapper bookOnBookTypeMapper;

    @Override
    public IPage<Book> select(Integer pageNum, Integer pageSize, String linkName) {
        LambdaQueryWrapper<Book> wrapper = new QueryWrapper<Book>().lambda();
        wrapper.orderByDesc(Book::getBId);
        if(!linkName.isEmpty())
            wrapper.like(Book::getName, linkName);
        Page<Book> page = new Page<>(pageNum, pageSize);
        IPage<Book> list = bookMapper.selectBookOnType(page, wrapper);
        return list;
    }

    @Override
    public Book insert(BookInsBody body,String token) {
        // 解析token数据，从token中获取用户id和学校id
        DecodedJWT tokenInfo = JwtUtils.getTokenInfo(token);
        Book.BookBuilder build = Book.builder()
            .name(body.getName())
            .title(body.getTitle())
            .price(body.getPrice())
            .intro(body.getIntro())
            .imgs(body.getImgs())
            .oldPrice(body.getOldPrice())
            .oldImgs(body.getOldImgs())
            .shopTime(body.getShopTime())
            .uId(tokenInfo.getClaim("uId").asString())
            .sId(tokenInfo.getClaim("sId").asString())
            .viewCount(0)
            .explain(body.getExplain())
            .status(0);
        // 获取封面，如果传入的图片数量大于0，则取第一张图片作为封面图片
        String[] imgs = body.getImgs() != null ? body.getImgs().split(",") : new String[0];
        if(imgs.length > 0){
            build.cover(imgs[0]);
        }
        Book data = build.build();
        int count = bookMapper.insert(data);
        if (count > 0) {
            QueryWrapper<BookOnType> onTypeWrapper = new QueryWrapper<>();
            onTypeWrapper.eq("b_id", data.getBId());
            bookOnBookTypeMapper.delete(onTypeWrapper);
            String[] typeList = body.getBTypes().split(",");
            for (String s : typeList) {
                bookOnBookTypeMapper.insert(new BookOnType(data.getBId(), Integer.parseInt(s)));
            }
            return data;
        }
        // 书籍添加失败
        return null;
    }

    @Override
    public boolean delete(List<Integer> bIds) {
        // 1. 删除所有书籍-书籍类型的关联数据
        if (bIds.size() > 0) {
            QueryWrapper<BookOnType> typeQueryWrapper = new QueryWrapper<>();
            typeQueryWrapper.in("b_id", bIds);
            bookOnBookTypeMapper.delete(typeQueryWrapper);
            QueryWrapper<Book> bookQueryWrapper = new QueryWrapper<>();
            bookQueryWrapper.in("b_id", bIds);
            bookMapper.delete(bookQueryWrapper);
        }
        return true;
    }

    @Override
    public boolean update(BookUpdateBody body) {
        QueryWrapper<BookOnType> typeQueryWrapper = new QueryWrapper<>();
        typeQueryWrapper.eq("b_id", body.getBId());
        bookOnBookTypeMapper.delete(typeQueryWrapper);
        Book book = Book.builder()
            .bId(body.getBId())
            .name(body.getName())
            .title(body.getTitle())
            .intro(body.getIntro())
            .price(body.getPrice())
            .imgs(body.getImgs())
            .oldPrice(body.getOldPrice())
            .oldImgs(body.getOldImgs())
            .shopTime(body.getShopTime())
            .cover(body.getCover())
            .explain(body.getExplain())
            .build();
        int count = bookMapper.updateById(book);
        String[] typeList = body.getBTypes().split(",");
        for (String s : typeList) {
            bookOnBookTypeMapper.insert(new BookOnType(book.getBId(), Integer.parseInt(s)));
        }
        return count > 0;
    }

    @Override
    public boolean setStatus(Integer bId, Integer status) {
        if(bId != null && status != null){
            Book book = Book.builder()
                .bId(bId)
                .status(status)
                .build();
            return bookMapper.updateById(book) > 0;
        }
        return false;
    }

    @Override
    public boolean viewBook(Integer bId) {
        if(bId != null){
            Book book = bookMapper.selectById(bId);
            book.setViewCount(book.getViewCount() + 1);
            return bookMapper.updateById(book) > 0;
        }
        return false;
    }

    @Override
    public boolean updateCover(Integer bId, String cover) {
        if(bId != null && cover != null){
            Book book = Book.builder()
                .bId(bId)
                .cover(cover)
                .build();
            return bookMapper.updateById(book) > 0;
        }
        return false;
    }

    @Override
    public IPage<Book> selectByUId(BookListByUIdParam param) {
        LambdaQueryWrapper<Book> wrapper = new QueryWrapper<Book>().lambda();
        wrapper.eq(Book::getUId, param.getUId());
        wrapper.orderByDesc(Book::getBId);
        if(param.getLinkName() != null && !param.getLinkName().isEmpty())
            wrapper.like(Book::getName, param.getLinkName());
        if(param.getState() != null)
            wrapper.eq(Book::getStatus, param.getState());
        if(param.getStartTime() != null)
            wrapper.ge(Book::getCreateTime, param.getStartTime());
        if(param.getEndTime() != null)
            wrapper.le(Book::getCreateTime, param.getEndTime());
        Page<Book> page = new Page<>(param.getPageNum(), param.getPageSize());
        return bookMapper.selectBookOnType(page, wrapper);
    }

    @Override
    public Book getById(Integer bid) {
        return bookMapper.selectBookById(bid);
    }
}
